﻿#pragma once

#include <cassert>


/*!
\brief 单例对象的基类
\tparam T 单例类的类型
\tparam is_auto_create 是否在获取单例对象时自动创建对象
*/
template <typename T, bool is_auto_create = true>
class FSingleton
{
public:
	virtual ~FSingleton()
	{
	}

	FSingleton(const FSingleton&) = delete;

	//! 获取单例对象的实例
	/*!
	\return T*
	*/
	static T* GetInstance()
	{
		static T t;
		return &t;
	}
protected:
	FSingleton()
	{
	}
};


template<typename T>
class FSingleton<T, false>
{
	static T* s_instance;
public:
	FSingleton()
	{
		assert(!s_instance && "已经构造该对象");
		s_instance = (T*)(this);
	}

	FSingleton(const FSingleton&) = delete;

	virtual ~FSingleton()
	{
		assert(s_instance && "对象没有创建");
		s_instance = nullptr;
	}
	//! 获取单例对象的实例
	/*!
	\return T*
	*/
	static T* GetInstance()
	{
		return s_instance;
	}
};

template<typename T>
__declspec(selectany) T* FSingleton<T, false>::s_instance = nullptr;

#define SINGLETON_CLASS(T) friend class FSingleton<T>;
